package com.roads.engineering.controller;

import com.roads.common.annotation.Log;
import com.roads.common.config.MasterConfig;
import com.roads.common.constant.Constants;
import com.roads.common.core.controller.BaseController;
import com.roads.common.core.domain.AjaxResult;
import com.roads.common.core.domain.FileEntity;
import com.roads.common.core.page.TableDataInfo;
import com.roads.common.enums.BusinessType;
import com.roads.common.utils.DateUtils;
import com.roads.common.utils.SecurityUtils;
import com.roads.common.utils.StringUtils;
import com.roads.common.utils.file.FileUploadUtils;
import com.roads.common.utils.file.FileUtils;
import com.roads.common.utils.file.MimeTypeUtils;
import com.roads.engineering.domain.EngMeterageChange;
import com.roads.engineering.domain.EngMeterageContract;
import com.roads.engineering.domain.EngMeterageDetailAnnex;
import com.roads.engineering.domain.EngMeterageExplain;
import com.roads.engineering.domain.EngMeterageMaster;
import com.roads.engineering.domain.EngMeterageOther;
import com.roads.engineering.domain.search.MeterageBoqModel;
import com.roads.engineering.service.IEngMeterageDetailService;
import com.roads.engineering.service.IEngMeterageMasterService;
import com.roads.project.domain.ProBoqMeterage;
import com.roads.project.domain.ProInstitution;
import com.roads.project.domain.ProInstitutionDetail;
import com.roads.project.service.IProBoqMeterageService;
import com.roads.project.service.IProInstitutionService;
import com.roads.workflow.domain.WorkflowTaskNode;
import com.roads.workflow.service.IWorkflowTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;

/**
 * @ClassName EngMeterageDetailController
 * @Description 工程计量详情controller
 * @Author nhp
 * @Date 2022/2/28 0028 16:43
 * @Version 1.0.0
 **/
@RestController
@RequestMapping("/engineering/meterage/detail")
public class EngMeterageDetailController extends BaseController {

    @Autowired
    private IEngMeterageMasterService masterService;

    @Autowired
    private IWorkflowTaskService taskService;

    @Autowired
    private IProInstitutionService institutionService;

    @Autowired
    private IProBoqMeterageService meterageService;

    @Autowired
    private IEngMeterageDetailService detailService;

    /**
     * 获取工程信息
     * 标段名称，工期名称，起始桩号，终止桩号，开工日期，完工日期
     *
     * @param masterId 主表ID
     * @return
     */
    @GetMapping(value = "/{masterId}")
    public AjaxResult getInfo(@PathVariable("masterId") Long masterId) {
        AjaxResult ajaxResult = new AjaxResult();
        EngMeterageMaster master = masterService.getModelById(masterId);
        ajaxResult.put("institutionName", master.getInstitutionName());
        ajaxResult.put("periodName", master.getPeriodName());
        return ajaxResult;
    }

    /**
     * 获取用户节点列表
     *
     * @param masterId 主键ID
     * @return 结果
     */
    @GetMapping(value = "/selectUserOptions/{masterId}")
    public AjaxResult selectUserOptions(@PathVariable("masterId") Long masterId) {
        AjaxResult result = new AjaxResult();
        EngMeterageMaster master = masterService.getModelById(masterId);
        List<WorkflowTaskNode> nodes = taskService.selectUserOptions(master.getUuid());
        result.put("currentUser", master.getCurrentUser());
        result.put("nodes", nodes);
        return result;
    }

    /**
     * 查询工程量清单
     *
     * @param model 工程量清单实体 meterageBoqId 暂存 工程计量主表ID
     * @return 合同计量清单或变更计量清单
     */
    @GetMapping("/selectMeterageBoqList")
    public TableDataInfo selectMeterageBoqList(MeterageBoqModel model) {
        EngMeterageMaster master = masterService.getModelById(model.getMasterId());
        ProInstitution institution = institutionService.getModelByInnerCode(master.getInstitutionCode());
        ProBoqMeterage search = new ProBoqMeterage();
        if (Constants.INSTITUTION_TYPE_F.equals(institution.getInstitutionType())) {
            // 分包如果共享清单，则取父项标段计量清单
            ProInstitution parent = institutionService.getModelByInnerCode(institution.getParentCode());
            if (Constants.YES.equals(parent.getIsShare())) {
                search.setInstitutionCode(parent.getInnerCode());
            } else {
                search.setInstitutionCode(master.getInstitutionCode());
            }
        } else {
            search.setInstitutionCode(master.getInstitutionCode());
        }
        search.setMeterageBoqType(model.getMeterageBoqType());
        search.setBoqCode(model.getBoqCode());
        search.setBoqName(model.getBoqName());
        search.setComplete(Constants.NO);
        startPage();
        List<ProBoqMeterage> list = meterageService.selectModelList(search);
        return getDataTable(list);
    }

    /**
     * 查询工程计量合同清单列表
     */
    @GetMapping("/listDetailContract")
    public TableDataInfo listDetailContract(EngMeterageContract model) {
        startPage();
        List<EngMeterageContract> list = detailService.selectContractList(model);
        return getDataTable(list);
    }

    /**
     * 查询工程计量变更清单列表
     */
    @GetMapping("/listDetailChange")
    public TableDataInfo listDetailChange(EngMeterageChange model) {
        startPage();
        List<EngMeterageChange> list = detailService.selectChangeList(model);
        return getDataTable(list);
    }

    /**
     * 查询工程计量其他支付项目列表
     */
    @GetMapping("/listDetailOther")
    public TableDataInfo listDetailOther(EngMeterageOther model) {
        startPage();
        List<EngMeterageOther> list = detailService.selectOtherList(model);
        return getDataTable(list);
    }

    /**
     * 查询工程计量填报说明
     */
    @GetMapping("/getDetailExplain")
    public AjaxResult getDetailExplain(EngMeterageExplain model) {
        EngMeterageExplain explain = detailService.getDetailExplainByUser(model.getMasterId(), model.getUser());
        return AjaxResult.success(explain);
    }

    /**
     * 批量新增合同清单
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:add')")
    @Log(title = "工程计量-合同清单", businessType = BusinessType.INSERT)
    @PostMapping("/saveContract")
    public AjaxResult saveContract(Long masterId, String ids) {
        return toAjax(detailService.saveContract(masterId, ids));
    }

    /**
     * 批量新增变更清单
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:add')")
    @Log(title = "工程计量-变更清单", businessType = BusinessType.INSERT)
    @PostMapping("/saveChange")
    public AjaxResult saveChange(Long masterId, String ids) {
        return toAjax(detailService.saveChange(masterId, ids));
    }

    /**
     * 获取工程计量-合同清单详细信息
     */
    @GetMapping(value = "/getDetailContract/{detailContractId}")
    public AjaxResult getDetailContract(@PathVariable("detailContractId") Long detailContractId) {
        AjaxResult ajaxResult = new AjaxResult();
        // 查询工程计量合同清单详情
        EngMeterageContract detail = detailService.getDetailContractById(detailContractId);
        // 查询计量清单
        ProBoqMeterage meterage = meterageService.getModelByCode(detail.getMeterageBoqCode());
        ajaxResult.put("detail", detail);
        ajaxResult.put("meterage", meterage);
        return ajaxResult;
    }

    /**
     * 获取工程计量-变更清单详细信息
     */
    @GetMapping(value = "/getDetailChange/{detailChangeId}")
    public AjaxResult getDetailChange(@PathVariable("detailChangeId") Long detailChangeId) {
        AjaxResult ajaxResult = new AjaxResult();
        // 查询工程计量变更清单详情
        EngMeterageChange detail = detailService.getDetailChangeById(detailChangeId);
        // 查询计量清单
        ProBoqMeterage meterage = meterageService.getModelByCode(detail.getMeterageBoqCode());
        ajaxResult.put("detail", detail);
        ajaxResult.put("meterage", meterage);
        return ajaxResult;
    }

    /**
     * 获取工程计量-其他支付项目详细信息
     */
    @GetMapping(value = "/getDetailOther/{detailOtherId}")
    public AjaxResult getDetailOther(@PathVariable("detailOtherId") Long detailOtherId) {
        return AjaxResult.success(detailService.getDetailOtherById(detailOtherId));
    }

    /**
     * 修改工程计量-合同清单详细信息
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:edit')")
    @Log(title = "工程计量-合同清单", businessType = BusinessType.UPDATE)
    @PostMapping("/updateDetailContract")
    public AjaxResult updateDetailContract(@RequestBody EngMeterageContract model) {
        // 超计量控制
        EngMeterageMaster master = masterService.getModelById(model.getMasterId());
        ProInstitution bid = institutionService.getModelByInnerCode(master.getInstitutionCode());
        // 默认不允许超计量
        String ultraMeasure = Constants.NO;
        // 如果是标段，则直接查看是否可以超计量，如果是分包，清单共享的情况下，需要看父项标段是否可以超计量
        if (Constants.INSTITUTION_TYPE_B.equals(bid.getInstitutionType())) {
            ProInstitutionDetail bidDetail = institutionService.getDetailModelByInnerCode(master.getInstitutionCode());
            ultraMeasure = bidDetail.getUltraMeasure();
        } else if (Constants.INSTITUTION_TYPE_F.equals(bid.getInstitutionType())) {
            ProInstitution parent = institutionService.getModelByInnerCode(bid.getParentCode());
            if (Constants.YES.equals(parent.getIsShare())) {
                ProInstitutionDetail parentDetail = institutionService.getDetailModelByInnerCode(parent.getInnerCode());
                ultraMeasure = parentDetail.getUltraMeasure();
            } else {
                ProInstitutionDetail bidDetail = institutionService.getDetailModelByInnerCode(bid.getInnerCode());
                ultraMeasure = bidDetail.getUltraMeasure();
            }
        }
        // 超计量控制，由数量和金额双向控制
        if (Constants.NO.equals(ultraMeasure)) {
            // 查询合同计量清单
            ProBoqMeterage meterage = meterageService.getModelByCode(model.getMeterageBoqCode());
            // 查询原有值
            EngMeterageContract old = detailService.getDetailContractById(model.getDetailContractId());
            BigDecimal oldAmount = old.getAmount() == null ? new BigDecimal(0) : old.getAmount();
            BigDecimal oldTotal = old.getTotal() == null ? new BigDecimal(0) : old.getTotal();
            BigDecimal newAmount = model.getAmount() == null ? new BigDecimal(0) : model.getAmount();
            BigDecimal newTotal = model.getTotal() == null ? new BigDecimal(0) : model.getTotal();
            String errorMessage = validateUltraMeasure(meterage, oldAmount, newAmount, oldTotal, newTotal);
            if (StringUtils.isNotEmpty(errorMessage)) {
                return error(errorMessage);
            }
        }
        return toAjax(detailService.updateDetailContract(model));
    }

    /**
     * 修改工程计量-变更清单详细信息
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:edit')")
    @Log(title = "工程计量-变更清单", businessType = BusinessType.UPDATE)
    @PostMapping("/updateDetailChange")
    public AjaxResult updateDetailChange(@RequestBody EngMeterageChange model) {
        // 超计量控制
        EngMeterageMaster master = masterService.getModelById(model.getMasterId());
        ProInstitution bid = institutionService.getModelByInnerCode(master.getInstitutionCode());
        // 默认不允许超计量
        String ultraMeasure = Constants.NO;
        // 如果是标段，则直接查看是否可以超计量，如果是分包，清单共享的情况下，需要看父项标段是否可以超计量
        if (Constants.INSTITUTION_TYPE_B.equals(bid.getInstitutionType())) {
            ProInstitutionDetail bidDetail = institutionService.getDetailModelByInnerCode(master.getInstitutionCode());
            ultraMeasure = bidDetail.getUltraMeasure();
        } else if (Constants.INSTITUTION_TYPE_F.equals(bid.getInstitutionType())) {
            ProInstitution parent = institutionService.getModelByInnerCode(bid.getParentCode());
            if (Constants.YES.equals(parent.getIsShare())) {
                ProInstitutionDetail parentDetail = institutionService.getDetailModelByInnerCode(parent.getInnerCode());
                ultraMeasure = parentDetail.getUltraMeasure();
            } else {
                ProInstitutionDetail bidDetail = institutionService.getDetailModelByInnerCode(bid.getInnerCode());
                ultraMeasure = bidDetail.getUltraMeasure();
            }
        }
        // 不允许超计量
        if (Constants.NO.equals(ultraMeasure)) {
            // 查询合同计量清单
            ProBoqMeterage meterage = meterageService.getModelByCode(model.getMeterageBoqCode());
            // 查询原有值
            EngMeterageChange old = detailService.getDetailChangeById(model.getDetailChangeId());
            BigDecimal oldAmount = old.getAmount() == null ? new BigDecimal(0) : old.getAmount();
            BigDecimal oldTotal = old.getTotal() == null ? new BigDecimal(0) : old.getTotal();
            BigDecimal newAmount = model.getAmount() == null ? new BigDecimal(0) : model.getAmount();
            BigDecimal newTotal = model.getTotal() == null ? new BigDecimal(0) : model.getTotal();
            String errorMessage = validateUltraMeasure(meterage, oldAmount, newAmount, oldTotal, newTotal);
            if (StringUtils.isNotEmpty(errorMessage)) {
                return error(errorMessage);
            }
        }
        return toAjax(detailService.updateDetailChange(model));
    }

    /**
     * 验证是否超计量，通过数量和金额进行双向控制
     * 首先判断计量清单是正数清单还是负数清单，如果是正数清单则需要判断数量和金额是否大于剩余数量和金额，如果是负数清单则需要判断数量和金额是否小于剩余数量和金额
     * @param meterage 计量清单
     * @param oldAmount 修改前数量
     * @param newAmount 修改数量
     * @param oldTotal 修改前金额
     * @param newTotal 修改金额
     * @return 结果
     */
    private String validateUltraMeasure(ProBoqMeterage meterage, BigDecimal oldAmount, BigDecimal newAmount, BigDecimal oldTotal, BigDecimal newTotal) {
        String errorMessage = "";
        // 合同数量，剩余数量，剩余金额
        BigDecimal meterageAmount = meterage.getAmount() == null ? new BigDecimal(0) : meterage.getAmount();
        BigDecimal meterageTotal = meterage.getTotal() == null ? new BigDecimal(0) : meterage.getTotal();
        BigDecimal remainderAmount = meterage.getRemainderAmount() == null ? new BigDecimal(0) : meterage.getRemainderAmount();
        BigDecimal remainderTotal = meterage.getRemainderTotal() == null ? new BigDecimal(0) : meterage.getRemainderTotal();
        // 剩余数量和剩余金额，需要添加修改前的数量和金额
        remainderAmount = remainderAmount.add(oldAmount);
        remainderTotal = remainderTotal.add(oldTotal);
        // 判断清单的合同数量是 正数还是负数, 默认true为正数，false为负数
        boolean flag = true;
        if (meterageAmount.compareTo(BigDecimal.ZERO) < 0) {
            flag = false;
        }
        if (flag) {
            if (newAmount.compareTo(remainderAmount) == 1) {
                BigDecimal alreadyAmount = meterage.getAlreadyAmount() == null ? new BigDecimal(0) : meterage.getAlreadyAmount();
                errorMessage = String.format("合同数量为：%s，已计量数量为：%s，剩余数量为：%s",
                        meterageAmount.stripTrailingZeros().toPlainString(),
                        alreadyAmount.subtract(oldAmount).stripTrailingZeros().toPlainString(),
                        remainderAmount.stripTrailingZeros().toPlainString());
                return errorMessage;
            }
            if (newTotal.compareTo(remainderTotal) == 1) {
                BigDecimal alreadyTotal = meterage.getAlreadyTotal() == null ? new BigDecimal(0) : meterage.getAlreadyTotal();
                errorMessage = String.format("合同金额为：%s，已计量金额为：%s，剩余金额为：%s",
                        meterageTotal.stripTrailingZeros().toPlainString(),
                        alreadyTotal.subtract(oldTotal).stripTrailingZeros().toPlainString(),
                        remainderTotal.stripTrailingZeros().toPlainString());
                return errorMessage;
            }
        } else {
            if (newAmount.compareTo(remainderAmount) == -1) {
                BigDecimal alreadyAmount = meterage.getAlreadyAmount() == null ? new BigDecimal(0) : meterage.getAlreadyAmount();
                errorMessage = String.format("合同数量为：%s，已计量数量为：%s，剩余数量为：%s",
                        meterageAmount.stripTrailingZeros().toPlainString(),
                        alreadyAmount.subtract(oldAmount).stripTrailingZeros().toPlainString(),
                        remainderAmount.stripTrailingZeros().toPlainString());
                return errorMessage;
            }
            if (newTotal.compareTo(remainderTotal) == -1) {
                BigDecimal alreadyTotal = meterage.getAlreadyTotal() == null ? new BigDecimal(0) : meterage.getAlreadyTotal();
                errorMessage = String.format("合同金额为：%s，已计量金额为：%s，剩余金额为：%s",
                        meterageTotal.stripTrailingZeros().toPlainString(),
                        alreadyTotal.subtract(oldTotal).stripTrailingZeros().toPlainString(),
                        remainderTotal.stripTrailingZeros().toPlainString());
                return errorMessage;
            }
        }
        return errorMessage;
    }

    /**
     * 修改工程计量-其他支付项目详细信息
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:edit')")
    @Log(title = "工程计量-其他支付项目", businessType = BusinessType.UPDATE)
    @PostMapping("/updateDetailOther")
    public AjaxResult updateDetailOther(@RequestBody EngMeterageOther model) {
        return toAjax(detailService.updateDetailOther(model));
    }

    /**
     * 修改工程计量-填报说明详细信息
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:edit')")
    @Log(title = "工程计量-填报说明", businessType = BusinessType.UPDATE)
    @PostMapping("/updateDetailExplain")
    public AjaxResult updateDetailExplain(@RequestBody EngMeterageExplain model) {
        return toAjax(detailService.updateDetailExplain(model));
    }

    /**
     * 删除工程计量-合同清单详细信息
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:remove')")
    @Log(title = "工程计量-合同清单", businessType = BusinessType.DELETE)
    @DeleteMapping("/deleteDetailContract/{ids}")
    public AjaxResult deleteDetailContract(@PathVariable Long[] ids) {
        if (StringUtils.isNull(ids) || ids.length == 0) {
            return error("请选择要删除的数据");
        }
        return toAjax(detailService.deleteContractByIds(ids));
    }

    /**
     * 删除工程计量-变更清单详细信息
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:remove')")
    @Log(title = "工程计量-变更清单", businessType = BusinessType.DELETE)
    @DeleteMapping("/deleteDetailChange/{ids}")
    public AjaxResult deleteDetailChange(@PathVariable Long[] ids) {
        if (StringUtils.isNull(ids) || ids.length == 0) {
            return error("请选择要删除的数据");
        }
        return toAjax(detailService.deleteChangeByIds(ids));
    }


    /**
     * 附件列表集合
     *
     * @param uuid uuid
     * @return 附件集合
     */
    @GetMapping("/getAnnexList")
    public AjaxResult getAnnexList(String uuid, Integer annexType) {
        EngMeterageDetailAnnex search = new EngMeterageDetailAnnex();
        search.setUuid(uuid);
        search.setAnnexType(annexType);
        List<EngMeterageDetailAnnex> list = detailService.selectAnnexList(search);
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("list", list);
        ajaxResult.put("annexCount", list.size());
        return ajaxResult;
    }

    /**
     * 附件上传
     *
     * @param file 文件
     * @param uuid uuid
     * @param annexType 附件类型
     * @return 结果
     * @throws Exception 异常
     */
    @PostMapping("/upload")
    public AjaxResult uploadAnnexFile(MultipartFile file, String uuid, Integer annexType, Long masterId, Integer type) throws Exception {
        int result = 0;
        try{
            EngMeterageMaster master = masterService.getModelById(masterId);
            String annexPath = MasterConfig.getUploadAnnexPath()
                    + "/" + Constants.MENU_TYPE_ENGINEERING
                    + "/" + master.getUuid()
                    + "/meterage/" + uuid + "/" + annexType;
            String fileName = file.getOriginalFilename();
            FileEntity fileEntity = FileUploadUtils.annexUpload(annexPath, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
            String filePath = fileEntity.getFilePath();
            String rename = filePath.substring(filePath.lastIndexOf("/") + 1);
            EngMeterageDetailAnnex annexFile = new EngMeterageDetailAnnex();
            annexFile.setType(type);
            annexFile.setRefilename(rename);
            annexFile.setFileName(fileName);
            if (fileEntity.getImage()) {
                annexFile.setIsImg(Constants.YES);
            } else {
                annexFile.setIsImg(Constants.NO);
            }
            annexFile.setFilePath(filePath);
            annexFile.setUuid(uuid);
            annexFile.setAnnexType(annexType);
            annexFile.setCreateBy(SecurityUtils.getUsername());
            annexFile.setCreateTime(DateUtils.getNowDate());
            result = detailService.insertAnnex(annexFile, annexType, uuid, type);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.success(result);
    }

    @GetMapping("/deleteAnnexFile")
    public AjaxResult deleteAnnexFile(Long fileId, Long masterId) {
        EngMeterageMaster master = masterService.getModelById(masterId);
        EngMeterageDetailAnnex file = detailService.getDetailAnnexById(fileId);
        String filePath = MasterConfig.getUploadAnnexPath()
                + "/" + Constants.MENU_TYPE_ENGINEERING
                + "/" + master.getUuid()
                + "/meterage/" + file.getUuid() + "/" + file.getAnnexType() + "/"  + file.getRefilename();
        FileUtils.deleteFile(filePath);
        int result = detailService.deleteAnnexById(fileId);
        return AjaxResult.success(result);
    }

    /**
     * 附件下载
     *
     * @param fileId 文件ID
     * @param response 响应
     * @param request 请求
     */
    @GetMapping("/downloadAnnexFile")
    public void downloadAnnexFile(Long fileId, Long masterId, HttpServletResponse response, HttpServletRequest request) {
        try {
            EngMeterageMaster master = masterService.getModelById(masterId);
            EngMeterageDetailAnnex file = detailService.getDetailAnnexById(fileId);
            String fileName = file.getFileName();
            String filePath = MasterConfig.getUploadAnnexPath()
                    + "/" + Constants.MENU_TYPE_ENGINEERING
                    + "/" + master.getUuid()
                    + "/meterage/" + file.getUuid() + "/" + file.getAnnexType() + "/"  + file.getRefilename();
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, fileName);
            FileUtils.writeBytes(filePath, response.getOutputStream());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 同步其他支付项目固定值
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:add')")
    @Log(title = "工程计量-其他支付项目", businessType = BusinessType.INSERT)
    @GetMapping(value = "/syncDetailItem/{masterId}")
    public AjaxResult syncDetailItem(@PathVariable("masterId") Long masterId) {
        return toAjax(detailService.syncDetailItem(masterId));
    }

    /**
     * 修改工程计量-变更清单详细信息
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:detail:add')")
    @Log(title = "工程计量-复制", businessType = BusinessType.INSERT)
    @PostMapping("/copy")
    public AjaxResult copy(@RequestBody EngMeterageContract model) {
        return toAjax(detailService.copy(model.getDetailContractId(), model.getAmount().intValue()));
    }

}
